﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Lyon.Remoting
{
    /// <summary>
    /// 描述给定的会话上下文。
    /// </summary>
    public class SessionContext
    {
        /// <summary>
        /// 公开服务名称
        /// </summary>
        static readonly public string ServiceName = "SessionContext.rem";

        string _IP;
        int _Port;
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="ip">地址</param>
        /// <param name="port">端口</param>
        public SessionContext(string ip, int port)
        {
            _IP = ip;
            _Port = port;
            GetService<ISessionContext>();
        }
        /// <summary>
        /// 连接到服务。
        /// </summary>
        /// <typeparam name="T">服务类型</typeparam>
        /// <returns></returns>
        public T GetService<T>()
        {
            ISessionContext context = SessionClient.Connect<ISessionContext>(_IP, _Port, ServiceName);
            string[] serviceNames = context.GetServiceNames(new ServiceTypeInfo(typeof(T)));
            if (serviceNames.Length == 0)
                return default(T);
            return SessionClient.Connect<T>(_IP, _Port, serviceNames[0]);
        }

        public interface ISessionContext
        {
            string[] GetServiceNames(ServiceTypeInfo typeInfo);
        }

        [Serializable]
        public class ServiceTypeInfo
        {
            static private string TypeToString(Type serviceType)
            {
                return serviceType.AssemblyQualifiedName;
            }
            static private Type StringToType(string typeToString)
            {
                return Type.GetType(typeToString);
            }

            string[] typeToStrings;
            /// <summary>
            /// 初始化服务类型信息。
            /// </summary>
            /// <param name="serviceTypes">服务类型</param>
            public ServiceTypeInfo(params Type[] serviceTypes)
            {
                Guard.ArgumentNotNullOrEmptyCollection(serviceTypes, "serviceTypes");
                typeToStrings = Array.ConvertAll<Type, string>(serviceTypes, delegate(Type item)
                {
                    return TypeToString(item);
                });
            }
            /// <summary>
            /// 确定当前服务类型是否为指定服务类型的子集。
            /// </summary>
            /// <param name="typeInfo"></param>
            /// <returns></returns>
            public bool IsSubsetOf(ServiceTypeInfo typeInfo)
            {
                foreach (string typeToString in typeToStrings)
                {
                    bool rs = Array.Exists<string>(typeInfo.typeToStrings, delegate(string item)
                    {
                        return item == typeToString;
                    });
                    if (!rs)
                        return false;
                }
                return true;
            }
            /// <summary>
            /// 是否为空
            /// </summary>
            public bool IsEmpty
            {
                get
                {
                    return typeToStrings.Length == 0;
                }
            }
        }
    }
    
    
}